﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Drawing;

namespace GDI_AnalysisComponents
{
    //命令类，处理文件输入、输出
    public class DCommand
    {
        public DCommand()
        {
        }

        public void SaveFiles(IWin32Window iwindow, GGraph ggraph)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "(对象系列化)GC文件 (*.GC)|*.GC|(ResultsMap)XML文件 (*.xml)|*.xml|(组件运行顺序)Boo文件 (*.boo)|*.boo";
            sfd.ShowDialog(iwindow);
            string FileName = sfd.FileName;
            try
            {
                if (File.Exists(FileName))
                {

                    File.Delete(FileName);
                }
                string fileExName = FileName.Remove(0, FileName.Length - 3);
                string str = null;
                switch (fileExName)
                {
                    case "xml":
                        break;
                    case "boo":
                        break;
                    default:
                        SaveFile(iwindow, ggraph);
                        break;
                }

                FileStream fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);

                byte[] info = new UTF8Encoding(true).GetBytes(str);

                fs.Write(info, 0, info.Length);
                fs.Flush();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }

        }
        //输出XML文档
        public string OutXML(IWin32Window iwindow, GGraph ggraph)
        {
            string s = null;
            s = s + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n\n";
            s = s + "<configuration>\r\n";
            s = s + "  <facilities>\r\n";
            s = s + "        <facility id=\"event.wiring\" type=\"Castle.Facilities.EventWiring.EventWiringFacility, Castle.MicroKernel\" />\r\n";
            s = s + "        <facility id=\"startable\" type=\"Castle.Facilities.Startable.StartableFacility, Castle.MicroKernel\" />\r\n";
            s = s + "  </facilities>\r\n";
            s = s + "   <components>\r\n";
            for (int i = 0; i <= ggraph.GcSavs.Count - 1; i++)
            {
                GComponent gc1 = (GComponent)(ggraph.GcSavs[i]);

                bool hasLine = false;
                for (int j = 0; j <= gc1.ParaGUnitList.Count - 1; j++)
                {
                    GUnit gun1 = (GUnit)(gc1.ParaGUnitList[j]);
                    if (gun1.FartherGUnitID != -1)
                    {
                        hasLine = true;
                    }
                }
                if (hasLine == true)
                {
                    s = s + "       <component id=\"" + gc1.ID + "\"  name=\"" + gc1.Name + "\" service=\"FlowEngine.IActivity,IFlow\" type=\"" + gc1.Type + "\" lifestyle=\"transient\">\r\n";
                    s = s + "           <results>\r\n";
                    for (int j = 0; j <= gc1.ParaGUnitList.Count - 1; j++)
                    {
                        GUnit gun1 = (GUnit)(gc1.ParaGUnitList[j]);
                        if (gun1.FartherGUnitID != -1)
                        {
                            for (int k = 0; k <= ggraph.GcSavs.Count - 1; k++)
                            {
                                GComponent gc2 = (GComponent)(ggraph.GcSavs[k]);
                                for (int l = 0; l <= gc2.ParaGUnitList.Count - 1; l++)
                                {
                                    GUnit gun2 = (GUnit)(gc2.ParaGUnitList[l]);
                                    if (gun2.ID == gun1.FartherGUnitID)
                                    {
                                        s = s + "               <result  name=\"" + gun1.Name + "\"  key=\"" + gun2.Name + "\" />\r\n";
                                    }
                                }
                            }
                        }
                    }
                    s = s + "           </results>\r\n";
                    s = s + "       </component>\r\n\n";
                }
                else
                    s = s + "       <component id=\"" + gc1.ID + "\"  name=\"" + gc1.Name + "\"  service=\"FlowEngine.IActivity,IFlow\" type=\"" + gc1.Type + "\" lifestyle=\"transient\" />\r\n";
            }
            s = s + "   </components>\r\n";
            s = s + "</configuration>";
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "XML文件 (*.xml)|*.xml|TXT文件 (*.txt)|*.txt|所有文件 (*.*)|*.*";
            sfd.ShowDialog(iwindow);
            string FileName = sfd.FileName;
            try
            {
                if (File.Exists(FileName))
                {
                    File.Delete(FileName);
                }
                FileStream fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                byte[] info = new UTF8Encoding(true).GetBytes(s);
                fs.Write(info, 0, info.Length);
                fs.Flush();
                s = "输出XML文档成功！已保存到:"+FileName;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                s = "输出XML文档失败！";
            }
            return s;
        }

        //保存文件GC
        public string SaveFile(IWin32Window iwindow, GGraph ggraph)
        {
            string s = null;
            SaveFileDialog sdlg = new SaveFileDialog();
            sdlg.Filter = "GC文件 (*.GC)|*.GC|所有文件 (*.*)|*.*";
            sdlg.ShowDialog(iwindow);
            string FileName = sdlg.FileName;

            try
            {
                if (File.Exists(FileName))
                {
                    File.Delete(FileName);
                }
                FileStream stream = new FileStream(FileName, System.IO.FileMode.Create);
                BinaryFormatter binary = new BinaryFormatter();
                binary.Serialize(stream, ggraph);
                stream.Close();
                s = "保存GC文件成功！已保存到:" + FileName;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
                s = "保存GC文件失败！";
            }
            return s;
        }

        //打开GC文件
        public GGraph OpenFile(IWin32Window iwindow, GGraph ggraph,ref string s)
        {
            OpenFileDialog odlg = new OpenFileDialog();
            odlg.Filter = "GC文件 (*.GC)|*.GC|所有文件 (*.*)|*.*";
            odlg.ShowDialog(iwindow);
            string FileName = odlg.FileName;
            if (File.Exists(FileName))
            {
                FileStream stream = new FileStream(FileName, FileMode.Open);
                BinaryFormatter binary = new BinaryFormatter();
                try
                {
                    ggraph = (GGraph)(binary.Deserialize(stream));
                    s="打开文件"+FileName+"成功！";
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    s="打开文件"+FileName+"失败！";
                }
                stream.Close();
            }

            int gcCount = 0;
            int gunCount = 0;
            //设置组件和单元的count值
            for (int i = 0; i < ggraph.GcSavs.Count; i++)
            {
                GComponent gc = (GComponent)(ggraph.GcSavs[i]);
                if (gc.ID > gcCount)
                {
                    gcCount = gc.ID;
                    gc.Count = gc.ID;
                }

                for (int j = 0; j < gc.ParaGUnitList.Count; j++)
                {
                    GUnit gun = (GUnit)(gc.ParaGUnitList[j]);
                    if (gun.ID > gunCount)
                    {
                        gunCount = gun.ID;
                        gun.Count = gun.ID;
                    }
                }
            }

            return ggraph;
        }



        //保存组件顺序
        public string OutSeqFile(IWin32Window iwindow, GGraph ggraph)
        {
            string s = null;
            if (IsHasNoUseGC(ggraph) == true || ggraph.GcSavs.Count == 0)
            {
                if (ggraph.GcSavs.Count == 0)
                    MessageBox.Show("没有组件");
                else
                    MessageBox.Show("存在未使用组件");
            }
            else
            {
                TopoSort(ggraph);
                ArrayList gcSeqLsit = ggraph.GcSeqLsit;
                int num = 0;
                for (int i = 0; i < gcSeqLsit.Count; i++)
                {
                    num++;
                    int prenum = num - 1;
                    GComponent gc = (GComponent)(gcSeqLsit[i]);
                    int gcid = gc.ID;
                    if (i == 0 && gcSeqLsit.Count != 1)
                        s = s + "result" + num + "=Do(\"" + gcid + "\",resultMap,config,objectFactory)\r\n";
                    else if (i != 0 && i == gcSeqLsit.Count - 1)
                        s = s + "Do(\"" + gcid + "\",result" + prenum + ",config,objectFactory)\r\n";
                    else if (i == 0 && i == gcSeqLsit.Count - 1)
                        s = s + "Do(\"" + gcid + "\",resultMap,config,objectFactory)\r\n";
                    else if (i != gcSeqLsit.Count - 1)
                        s = s + "result" + num + "=Do(\"" + gcid + "\"," + "result" + prenum + ",config,objectFactory)\r\n";
                }
                MessageBox.Show("" + s);

                SaveFileDialog sdlg = new SaveFileDialog();
                sdlg.Filter = "Boo文件 (*.boo)|*.boo|所有文件 (*.*)|*.*";
                sdlg.ShowDialog(iwindow);
                string FileName = sdlg.FileName;
                try
                {
                    if (File.Exists(FileName))
                    {
                        File.Delete(FileName);
                    }
                    FileStream fs = new FileStream(FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    byte[] info = new UTF8Encoding(true).GetBytes(s);
                    fs.Write(info, 0, info.Length);
                    fs.Flush();

                    s = "保存组件顺序成功！已保存到:" + FileName;
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                    s = "保存组件顺序失败！";
                }
            }

            return s;
        }

        //组件拓扑排序
        public void TopoSort(GGraph ggraph)
        {
            ArrayList gcSavsList = new ArrayList();
            ArrayList gcSavsTempList = new ArrayList();
            ArrayList gcIDSeqLsit = new ArrayList();
            ArrayList gcSeqLsit = ggraph.GcSeqLsit;

            for (int i = 0; i < ggraph.GcSavs.Count; i++)
            {
                GComponent gc = (GComponent)(ggraph.GcSavs[i]);
                gcSavsList.Add(gc);
                gcSavsTempList.Add(gc);
            }

            while (gcIDSeqLsit.Count != ggraph.GcSavs.Count)
            {
                //查找入度为0的组件
                for (int i = 0; i < gcSavsTempList.Count; i++)
                {
                    GComponent gc = (GComponent)gcSavsTempList[i];
                    if (gc.InGunSList.Count == 0)
                    {
                        gcIDSeqLsit.Add(gc.ID);
                        gcSeqLsit.Add(gc);
                        gcSavsList.Remove(gc);
                    }
                }
                gcSavsTempList = gcSavsList;

                //删除入度
                for (int i = 0; i < gcSavsTempList.Count; i++)
                {
                    GComponent gc = (GComponent)gcSavsTempList[i];
                    for (int j = 0; j < gc.InGunSList.Count; j++)
                    {
                        int ingcid = (int)(gc.InGunSList[j]);
                        for (int k = 0; k < gcIDSeqLsit.Count; k++)
                        {
                            int gcid = (int)gcIDSeqLsit[k];
                            if (ingcid == gcid)
                                (gc.InGunSList).Remove(ingcid);
                        }
                    }
                }
                gcSavsList = gcSavsTempList;

            }

            //恢复组件入度
            for (int i = 0; i < ggraph.GcSavs.Count; i++)
            {
                GComponent gc = (GComponent)(ggraph.GcSavs[i]);
                for (int j = 0; j < gc.ParaGUnitList.Count; j++)
                {
                    GUnit gun = (GUnit)(gc.ParaGUnitList[j]);
                    if (gun.FartherGUnitID != -1)
                    {
                        for (int k = 0; k < ggraph.GcSavs.Count; k++)
                        {
                            GComponent gc0 = (GComponent)(ggraph.GcSavs[k]);
                            for (int l = 0; l < gc0.ParaGUnitList.Count; l++)
                            {
                                GUnit gun0 = (GUnit)(gc0.ParaGUnitList[l]);
                                if (gun0.ID == gun.FartherGUnitID)
                                    gc.InGunSList.Add(gc0.ID);
                            }
                        }
                    }
                }
            }

        }

        //判断是否有未用的组件
        public bool IsHasNoUseGC(GGraph ggraph)
        {
            bool HASNOUSEGC = false;

            if (ggraph.GcSavs.Count != 1)
                for (int i = 0; i < ggraph.GcSavs.Count; i++)
                {
                    GComponent gc1 = (GComponent)(ggraph.GcSavs[i]);
                    if (gc1.InGunSList.Count == 0)
                    {
                        bool f = true;
                        for (int j = 0; j < ggraph.GcSavs.Count; j++)
                        {
                            GComponent gc2 = (GComponent)(ggraph.GcSavs[j]);
                            if (gc2.InGunSList.Count != 0)
                            {
                                for (int k = 0; k < gc2.InGunSList.Count; k++)
                                {
                                    int gcid = (int)(gc2.InGunSList[k]);

                                    if (gcid == gc1.ID)
                                        f = false;
                                }
                            }
                        }
                        if (f == true)
                            HASNOUSEGC = true;
                    }
                }

            return HASNOUSEGC;
        }

        //删除组件
        public string DeleteGcomponent(GGraph ggraph)
        {
            string s = null;
            if (ggraph.GcSels.Count == 0)
            {
                s = "对不起，没有选择任何组件！";
                MessageBox.Show("" + ggraph.GcSels.Count);
            }
            else
            {
                s = s + "组件";
                for (int i = 0; i < ggraph.GcSels.Count; i++)
                {
                    GComponent gc1 = (GComponent)(ggraph.GcSels[i]);
                    s = s + "" + gc1.Name;
                    for (int j = 0; j < gc1.ParaGUnitList.Count; j++)
                    {
                        GUnit gun1 = (GUnit)(gc1.ParaGUnitList[j]);
                        for (int k = 0; k < ggraph.GcSavs.Count; k++)
                        {
                            GComponent gc2 = (GComponent)(ggraph.GcSavs[k]);
                            //清楚连线入度
                            gc2.InGunSList.Remove(gc1.ID);

                            for (int l = 0; l < gc2.ParaGUnitList.Count; l++)
                            {
                                GUnit gun2 = (GUnit)(gc2.ParaGUnitList[l]);
                                //清楚连线
                                if (gun1.FartherGUnitID == gun2.ID)
                                {
                                    //  MessageBox.Show("1111111111" + gun2.GComponentId+gun1.GComponentId);
                                    for (int n = 0; n < ggraph.LineSavs.Count; n++)
                                    {
                                        GLinkGUnits glg = (GLinkGUnits)ggraph.LineSavs[n];
                                        if (glg.EndGun == gun1)
                                            ggraph.LineSavs.Remove(glg);
                                    }
                                    // GLinkGUnits glg = (gun2,gun1);
                                    gun1.FartherGUnitID = -1;
                                }
                                if (gun2.FartherGUnitID == gun1.ID)
                                {
                                    for (int n = 0; n < ggraph.LineSavs.Count; n++)
                                    {
                                        GLinkGUnits glg = (GLinkGUnits)ggraph.LineSavs[n];
                                        if (glg.EndGun == gun2)
                                            ggraph.LineSavs.Remove(glg);
                                    }
                                    gun2.FartherGUnitID = -1;
                                }
                            }
                        }
                    }
                    ggraph.GcSavs.Remove(gc1);
                }
                s = s + "已删除！";
            }

            ggraph.GcSels.Clear();

            return s;
        }

        //删除连线
        public string DeleGLinkLine(GGraph ggraph)
        {
            string s = null;
            if (ggraph.LineSels != null)
            {
                s = "连线已删除！";
                for (int i = 0; i < ggraph.LineSels.Count; i++)
                {
                    GLinkGUnits glg = (GLinkGUnits)(ggraph.LineSels[i]);
                    glg.EndGun.FartherGUnitID = -1;
                    ggraph.LineSavs.Remove(glg);

                    for (int j = 0; j < ggraph.GcSavs.Count; j++)
                    {
                        GComponent gc = (GComponent)(ggraph.GcSavs[j]);
                        if (gc.ID == glg.EndGun.GComponentId)
                            gc.InGunSList.Remove(glg.StartGun.GComponentId);
                    }
                }
            }
            else
                s = "对不起，你没有选中连线！";
            ggraph.LineSels.Clear();
            return s;
        }

        //删除所有的连线
        public string DeleAllGLinkLine(GGraph ggraph)
        {
            string s = null;
            ggraph.LineSavs.Clear();
            s = "所有连线已删除！";
            return s;
        }

        //新建文件
        public string NewFile(GGraph ggraph)
        {
            string s = null;
            ggraph.Clear();
            s = "已新建文件！";
            return s;
        }
    }
}
